//-----------------------------------------------------------------------
// <copyright file="IMAddress.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace Microsoft.Live.Messenger
{
    using System;
    using System.ComponentModel;
    using Microsoft.Live.Core;

    /// <summary>
    /// Represents an instant messaging address.
    /// </summary>
    /// <remarks>
    /// Instant messaging addresses are composed of an address and an associated <see cref="IMAddressType"/>. 
    /// </remarks>
    public sealed class IMAddress : INotifyPropertyChanged
    {
        private readonly MessengerEntity entity;
        private readonly User user;

        private IMAddressPresence presence;
        private EndpointCollection endpoints;
        private Capabilities capabilities;

        internal IMAddress(MessengerEntity entity, User user)
        {
            this.entity = entity;
            this.entity.AttachEvent("PropertyChanged", this.OnPropertyChanged);

            this.user = user;
        }

        internal MessengerEntity Entity
        {
            get { return this.entity; }
        }

        public bool IsUser
        {
            get { return this.user.Address == this; } // bugbug should expose
        }

        internal User User
        {
            get { return this.user; }
        }

        /// <summary>
        /// Gets a string containing the address.
        /// </summary>
        public string Address
        {
            get { return this.entity.GetProperty<string>("Address"); }
        }

        /// <summary>
        /// Gets the message type of the address.
        /// </summary>
        public IMAddressType Type
        {
            get { return this.entity.GetEnumProperty<IMAddressType>("Type"); }
        }

        /// <summary>
        /// Gets the collection of endpoints.
        /// </summary>
        public EndpointCollection Endpoints
        {
            get
            {
                if (this.endpoints == null)
                {
                    this.endpoints = new EndpointCollection(this.entity.GetProperty("Endpoints"), this.user);
                }
                return this.endpoints;
            }
        }

        /// <summary>
        /// Gets the capabilities of the instant messaging address.
        /// </summary>
        public Capabilities Capabilities
        {
            get
            {
                if (this.capabilities == null)
                {
                    this.capabilities = new Capabilities(this.entity.GetProperty("Capabilities"), this);
                }
                return this.capabilities;
            }
        }

        /// <summary>
        /// Gets the presence information associated with the address.
        /// </summary>
        public IMAddressPresence Presence
        {
            get
            {
                if (this.presence == null)
                {
                    this.presence = new IMAddressPresence(this.entity.GetProperty("Presence"), this);
                }
                return this.presence;
            }
        }

        /// <summary>
        /// Gets whether the address is online at the moment.
        /// </summary>
        public bool IsOnline
        {
            get { return this.entity.GetProperty<bool>("IsOnline"); }
        }

        /// <summary>
        /// Gets whether the address is federated.
        /// </summary>
        public bool IsFederated
        {
            get { return this.entity.GetProperty<bool>("IsFederated"); }
        }

        #region INotifyPropertyChanged Members

        /// <summary>
        /// Occurs when a property value changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        /// <summary>
        /// Determines whether the other instant messaging address equals this one.
        /// </summary>
        /// <param name="other">The other address.</param>
        /// <returns><c>true</c> if the addresses are equal; otherwise <c>false</c>.</returns>
        public bool Equals(IMAddress other)
        {
            return (bool)this.entity.Invoke("Equals", other.Entity);
        }

        /// <summary>
        /// Gets whether the Identity is verified.
        /// </summary>
        public bool IsIdentityVerified
        {
            get { return this.entity.GetProperty<bool>("IsIdentityVerified"); }
        }

        /// <summary>
        /// Gets the network icon URL for the instant messaging address.
        /// </summary>
        public Uri NetworkIconUrl
        {
            get { return this.entity.GetUriProperty("NetworkIconUrl"); }
        }

        private void OnPropertyChanged(object sender, MessengerEventArgs e)
        {
            this.OnPropertyChanged(
                new PropertyChangedEventArgs(
                    e.Entity.GetProperty<string>("PropertyName")));
        }

        private void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, e);
            }
        } 
    }
}
